/********************************************************************
	created:	2008/06/27
	created:	27:6:2008   15:52
	file base:	CommAlg
	file ext:	h
	author:		lingfei.tang
*********************************************************************/

#if !defined(__ALG_COMM_ALG___)
#define __ALG_COMM_ALG___
#include "algdef.h"
#include <algorithm>
#include <boost/bind.hpp>
#include <iostream>
#include <math.h>

#if !defined(FLT_DEC)
#define FLT_DEC    0.000001f
#endif

long F2I_DEC(float fv);

long ROUND_DEC(float fv);

BEGIN_ALG
float __abs(float v);
double __abs(double v);
int __abs(int v);
/*
template<typename T> typename T::iterator 
find_nearest_value(T &c, typename const T::value_type value)
{
	typedef typename T::value_type value_type;
	typedef typename T::iterator ITERATOR;	

	ITERATOR pos = c.end();
	if (c.empty())
	{
		return pos;
	}

	value_type MIN_DIF = __abs(c.front() - value);
	for (ITERATOR it = c.begin(); it != c.end(); ++it)
	{
		if (__abs(*it - value) < MIN_DIF )
		{
			MIN_DIF = __abs(*it - value);
			pos = it;
		}
	}
	return pos;
}
*/
template<typename T> typename T::iterator 
find_nearest_value(T &c, typename const T::value_type value)
{
	typedef typename T::value_type value_type;
	typedef typename T::iterator ITERATOR;	
	
	ITERATOR pos = c.end();
	if (c.empty())
	{
		return pos;
	}
	
	value_type MIN_DIF = __abs(c.front() - value);
	for (ITERATOR it = c.begin(); it != c.end(); ++it)
	{
		if (__abs(*it - value) < MIN_DIF )
		{
			MIN_DIF = __abs(*it - value);
			pos = it;
		}
	}
	return pos;
}


template<typename T>bool 
__abs_less(T v1, T v2){return __abs(v1) < __abs(v2);}
template <typename T>bool 
__abs_greate(T v1, T v2){return __abs(v1) > __abs(v2);}

template<typename T> typename T::value_type 
find_maxabsdiff_value(const T &c1, const T &c2, T &dif_c)
{
	T::const_iterator begin = c1.begin();
	T::const_iterator end = c1.end(); 
	
	T::const_iterator begin2 = c2.begin();
	typedef T::value_type VALUETYPE;

	dif_c.resize(c1.size());

	std::transform(begin, end, begin2, dif_c.begin(), 
		std::minus<VALUETYPE>());
	VALUETYPE max = *std::max_element(dif_c.begin(), dif_c.end());
	VALUETYPE min = *std::min_element(dif_c.begin(), dif_c.end());
	if(__abs_greate(max, min)) 
		return max ;
	return min;
}

END_ALG
#endif